package com.bsgogogo.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.bsgogogo.common.Result;
import com.bsgogogo.common.ResultCode;
import com.bsgogogo.entity.Account;
import com.bsgogogo.entity.AuthorityInfo;
import com.bsgogogo.exception.CustomException;
import com.bsgogogo.entity.AdminInfo;
import com.bsgogogo.entity.UserInfo;

import com.bsgogogo.service.AdminInfoService;
import com.bsgogogo.service.UserInfoService;

import org.springframework.web.bind.annotation.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import cn.hutool.json.JSONUtil;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 账户控制层
 */

@RestController
//前台登录或注册功能最先进入该层 用Account封装用户和管理员
public class AccountController {

    @Value("${authority.info}") // 从application.yml中引入authority.info
    private String authorityStr;

	@Resource
	private AdminInfoService adminInfoService;
	@Resource
	private UserInfoService userInfoService;


    @PostMapping("/login")
    public Result<Account> login(@RequestBody Account account, HttpServletRequest request) {
        if (StrUtil.isBlank(account.getName()) || StrUtil.isBlank(account.getPassword()) || account.getLevel() == null) {
            throw new CustomException(ResultCode.PARAM_LOST_ERROR);
        }
        Integer level = account.getLevel();
        Account login = new Account();
        //判断是用户还是管理员登录
		if (1 == level) {
			login = adminInfoService.login(account.getName(), account.getPassword());
		}
		if (2 == level) {
			login = userInfoService.login(account.getName(), account.getPassword());
		}

        request.getSession().setAttribute("user", login);
        return Result.success(login);
    }

    @PostMapping("/register")
    //注册
    public Result<Account> register(@RequestBody Account account) {
        Integer level = account.getLevel();
        Account login = new Account();
		if (1 == level) {//注册管理员
			AdminInfo info = new AdminInfo();
			BeanUtils.copyProperties(account, info); //转换类 赋给AdminInfo
			login = adminInfoService.add(info);
		}
		if (2 == level) { //注册用户
			UserInfo info = new UserInfo();
			BeanUtils.copyProperties(account, info);
			login = userInfoService.add(info);
		}

        return Result.success(login);
    }

    //退出登录
    @GetMapping("/logout")
    public Result logout(HttpServletRequest request) {
        request.getSession().setAttribute("user", null);
        return Result.success();
    }

    //用于拦截器
    @GetMapping("/auth")
    public Result getAuth(HttpServletRequest request) {
        Object user = request.getSession().getAttribute("user");
        if(user == null) {
            return Result.error("401", "未登录");
        }
        return Result.success(user);
    }

    //后台获取当前用户个人信息
    @GetMapping("/getAccountInfo")
    public Result<Object> getAccountInfo(HttpServletRequest request) {
        Account account = (Account) request.getSession().getAttribute("user");
        if (account == null) {
            return Result.success(new Object());
        }
        Integer level = account.getLevel();
		if (1 == level) { //管理员
			return Result.success(adminInfoService.findById(account.getId()));
		}
		if (2 == level) {
			return Result.success(userInfoService.findById(account.getId()));
		}

        return Result.success(new Object());
    }

    @GetMapping("/getSession")
    public Result<Map<String, String>> getSession(HttpServletRequest request) {
        Account account = (Account) request.getSession().getAttribute("user");
        if (account == null) {
            return Result.success(new HashMap<>(1));
        }
        Map<String, String> map = new HashMap<>(1);
        map.put("username", account.getName());
        return Result.success(map);
    }

    //先导入自己定义的侧边栏JSON设计
    @GetMapping("/getAuthority")
    public Result<List<AuthorityInfo>> getAuthorityInfo() {
        List<AuthorityInfo> authorityInfoList = JSONUtil.toList(JSONUtil.parseArray(authorityStr), AuthorityInfo.class);
        return Result.success(authorityInfoList);
    }

    /**
    * 获取当前用户所能看到的模块信息
    * @param request
    * @return
    */
    @GetMapping("/authority")
    public Result<List<Integer>> getAuthorityInfo(HttpServletRequest request) {
        Account user = (Account) request.getSession().getAttribute("user");
        if (user == null) {
            return Result.success(new ArrayList<>());
        }
        //objects放入的是写入的字符串 用于区分模块
        JSONArray objects = JSONUtil.parseArray(authorityStr); //转换成数组对象
        for (Object object : objects) { //遍历数组对象
            JSONObject jsonObject = (JSONObject) object; //转换成JSONObject对象
            if (user.getLevel().equals(jsonObject.getInt("level"))) { //看是否是用户或者管理员
                JSONArray array = JSONUtil.parseArray(jsonObject.getStr("models")); //将models在划分成数组对象赋给array
                List<Integer> modelIdList = array.stream().map((o -> {
                    JSONObject obj = (JSONObject) o;    //映射
                    return obj.getInt("modelId"); //获取账户的当前modelid
                    })).collect(Collectors.toList());
                System.out.println(modelIdList);
                return Result.success(modelIdList);  //返回当前对应账户的modelid集合
            }
        }
        return Result.success(new ArrayList<>());
    }

    //侧边栏展示 modelId对应前端展示不同模块信息
    @GetMapping("/permission/{modelId}")
    public Result<List<Integer>> getPermission(@PathVariable Integer modelId, HttpServletRequest request) {
        List<AuthorityInfo> authorityInfoList = JSONUtil.toList(JSONUtil.parseArray(authorityStr), AuthorityInfo.class); //字符串转换并接收到AuthorityInfo集合中
        Account user = (Account) request.getSession().getAttribute("user");
        if (user == null) {
            return Result.success(new ArrayList<>());
        }
        Optional<AuthorityInfo> optional = authorityInfoList.stream().filter(x -> x.getLevel().equals(user.getLevel())).findFirst(); //过滤找到对应账户
        if (optional.isPresent()) { //对象存在
            Optional<AuthorityInfo.Model> firstOption = optional.get().getModels().stream().filter(x -> x.getModelId().equals(modelId)).findFirst();//过滤器找到对应modelID
            if (firstOption.isPresent()) { //找到对应modelid的operation数组 并放入info集合中
                List<Integer> info = firstOption.get().getOperation();
                return Result.success(info);
            }
        }
        return Result.success(new ArrayList<>());
    }

    //更新密码 管理员、用户共用
    @PutMapping("/updatePassword")
    public Result updatePassword(@RequestBody Account info, HttpServletRequest request) {
        Account account = (Account) request.getSession().getAttribute("user");
        if (account == null) {
            return Result.error(ResultCode.USER_NOT_EXIST_ERROR.code, ResultCode.USER_NOT_EXIST_ERROR.msg);
        }
        String oldPassword = SecureUtil.md5(info.getPassword());
        if (!oldPassword.equals(account.getPassword())) {
            return Result.error(ResultCode.PARAM_PASSWORD_ERROR.code, ResultCode.PARAM_PASSWORD_ERROR.msg);
        }
        info.setPassword(SecureUtil.md5(info.getNewPassword())); //前台输入的新密码
        Integer level = account.getLevel();
		if (1 == level) {
			AdminInfo adminInfo = new AdminInfo();
			BeanUtils.copyProperties(info, adminInfo);
			adminInfoService.update(adminInfo);
		}
		if (2 == level) {
			UserInfo userInfo = new UserInfo();
			BeanUtils.copyProperties(info, userInfo);
			userInfoService.update(userInfo);
		}

        info.setLevel(level);
        info.setName(account.getName());
        // 清空session，让用户重新登录
        request.getSession().setAttribute("user", null);
        return Result.success();
    }

    //重置密码 供忘记密码按钮使用
    @PostMapping("/resetPassword")
    public Result resetPassword(@RequestBody Account account) {
        Integer level = account.getLevel();
		if (1 == level) {
			AdminInfo info = adminInfoService.findByUserName(account.getName());
			if (info == null) {
				return Result.error(ResultCode.USER_NOT_EXIST_ERROR.code, ResultCode.USER_NOT_EXIST_ERROR.msg);
			}
			info.setPassword(SecureUtil.md5("123456"));
			adminInfoService.update(info);
		}
		if (2 == level) {
			UserInfo info = userInfoService.findByUserName(account.getName());
			if (info == null) {
				return Result.error(ResultCode.USER_NOT_EXIST_ERROR.code, ResultCode.USER_NOT_EXIST_ERROR.msg);
			}
			info.setPassword(SecureUtil.md5("123456"));
			userInfoService.update(info);
		}

        return Result.success();
    }
}
